Skip to main content

Data Fetching and Revalidation

Data inside a route can be fetched using two functions:

Client Fetcher - Executes on client side navigation or absence of server fetcher.

Server Fetcher - Executes on when client requests server for a page during first paint (SSR).

  const HomePage = ()=><div>HomePage</div>

//Fetcher functions returning Promise
HomePage.clientFetcher = (routerProps,fetcherArgs) => { return new Promise()}

HomePage.serverFetcher = (serverRouterProps,fetcherArgs) => { return new Promise()}

Both clientFetcher and serverFetcher functions should either return a promise or should be async functions.

Data fetched through clientFetcher or serverFetcher will not be re-fetched once it is fetched unless refetch or clear are used.

We'll talk about revalidation in detail in further sections.


Client Fetcher

clientFetcher will be called during client side navigation, when navigating through <Link/> or <Navigate> components or by using hooks like useNavigate provided by router.

clientFetcher will not be executed on app load on the client in case serverFetcher was executed on the server.

Client side navigation in @tata1mg/router is based on react-router-v6.

Home.clientFetcher = async ({route,location,params,searchParams,navigate},{store}) => {
const res = await fetch("some_url");
const json = await res.json();
return json;
};

Type definition

/**
* @typedef FetcherParams
* @property {any} route Route object defined in routes array
* @property {import("react-router-dom").Location} location the current location object, which represents the current URL in web browsers.
* @property {import("react-router-dom").Params} params object of key/value pairs of the dynamic params from the current URL that were matched by the route path.
* @property {URLSearchParams} searchParams search parameters via URLSearchParams interface.
* @property {import("react-router-dom").Navigate} navigate function to navigate to other pages based on response.
*/
/**
* @description Fetcher function to fetch page data returns a promise which resolve or reject to set data or error in RouterContext
* @param {FetcherParams} fetcherParams
* @param {any} fetcherArgs anything passed in fetcherArgs prop of RouterProvider
* @returns Promise<any>
*/
export const clientFetcher = ({ route, location, params, searchParams, navigate }, fetcherArgs) => {
return new Promise()
}


Server Fetcher

serverFetcher will be called during the first fold request or when navigation is done by window.location.href or similar methods. It will only be called on the server and will not be included in the client bundle, so it is safe to use server only secrets in this function.

Home.serverFunction = async ({route, location, params, searchParams, navigate},{store}) => {
const res = await fetch("some_url");
const json = await res.json();
return json;
};

Type Definition

/**
* @typedef FetcherParams
* @property {any} route Route object defined in routes array
* @property {import("react-router-dom").Location} location the current location object, which represents the current URL in web browsers.
* @property {import("react-router-dom").Params} params object of key/value pairs of the dynamic params from the current URL that were matched by the route path.
* @property {URLSearchParams} searchParams search parameters via URLSearchParams interface.
* @property {import("react-router-dom").Navigate} navigate function to navigate to other pages based on response.
*/
/**
* @description Fetcher function to fetch page data returns a promise which resolve or reject to set data or error in RouterContext
* @param {FetcherParams} fetcherParams
* @param {any} fetcherArgs anything passed in fetcherArgs prop of RouterProvider
* @returns Promise<any>
*/
export const serverFetcher = ({ route, location, params, searchParams, navigate }, fetcherArgs) => {
return new Promise()
}

Accessing data from router

useCurrentRouteData hook

useCurrentRouteData hook from @tata1mg/router returns the current router context object with data, error, isFetching, isFetched, refetch and clear properties.

Details of each property are provided below :

KeyState
isFetchingData fetching is in progress
isFetchedFetcher function is resolved/rejected
errorError object thrown by clientFetcher
dataData object returned by clientFetcher
refetchA function that can be called to manually trigger clientFetcher of the route.
clearFunction to clear route cache for a particular route

Example :

import { useCurrentRouteData } from "@tata1mg/router"

const Home = () => {

const { isFetching, isFetched, error, data, refetch, clear } = useCurrentRouteData()

}

Home.clientFetcher = async () => {
return {status:200}
}

useRouterData hook

The useRouterData hook returns a router context object with data of all the fetchers in the current route tree.

  // route: /a/b
import { useRouterData } from '@tata1mg/router';
const routerData = useRouterData();
//Supposed you have /a route and /b as child route and attached fetchers to all the routes following is going to be the structure of routerData
{
"/a/b":{ isFetching , isFetched , error , data }, "index/a":{ isFetching , isFetched , error , data }
}

Revalidating data

For data revalidation, refetch and clear functions are used. They are accessed through the useCurrentRouteData hook

Refetch

refetch executes the client loader. A custom argument can be passed while calling it through refetch in client loader to handle use cases where the fetch function needs to access the application state like for pagination, infinite scroll, etc.

The custom argument passed by refetch will be available as the third argument of in clientFetcher

Example :

const Home = () => {
...
useEffect(()=>{
refetch({pageNo})
},[pageNo])
}

Home.clientFetcher = async ({},{},{pageNo}) => {
const res = await fetch(`some_url/${pageNo}`)
const json = await res.json()
return json
}

Clear

The clear function clears the data for the particular route from where it is called.

Example :

const Home = () => {
...
useEffect(()=>{
clear()
},[pathname])

//will clear data for this particular route on navigation

}